
package main

import "fmt"

func main(){
//	printType()
//	type_switch()
	type_ident()
}

func printType(){
	var s ts=ts{"hello"}
	var i ti=&s
	fmt.Println("start to show type")
	fmt.Printf("Type of  :\n")
	fmt.Printf("Type of int : %T\n",3)
	fmt.Printf("Type of string : %T\n","hello")
	fmt.Printf("Type of bool : %T \n",true)
	fmt.Printf("Type of struct : %T \n",s)
	fmt.Printf("Type of interface %T :\n",i)
	fmt.Printf("Type of func : %T\n",test1)
//	fmt.Printf("Type of pakcage : %T\n",fmt)
	
}

func type_switch(){
	var s ts=ts{"world"}
	check_type(s)
	var i ti=&s
	check_type(i)
	var ss string="talk"
	check_type(ss)
	var n int=32
	check_type(n)
	var v float32=3.25423
	check_type(v)
	
	check_type(test1)
	
	var ii []int=[]int{1,2,3,4}
	check_type(ii)
}

func check_type(t interface{}){
	fmt.Println("enter check_type ",t)
	switch t.(type){
		case int:
		fmt.Println("type is : int ",t)
		case float32:
		fmt.Println("type is : float32 ",t)
		case ts:
		fmt.Println("type is struct :",t)
		case string:
		fmt.Println("type is string : ",t,t.(string))
		case func():
		fmt.Println("type is func : ",t)
		case []int:
		fmt.Println("type is array of int : ",t)
		case interface{}: // interface{} means any type
		fmt.Println("type is interface : ",t)
		default:
		fmt.Println("------other type ")
	}
	fmt.Println("enf of check_type ",t)
	fmt.Println()
}

func type_ident(){
	var i int=23
	type_ident_sub(i)
	var ii []int=[]int{1,2,3,4}
	type_ident_sub(ii)
	var s string="abcdefg"
	type_ident_sub(s)
	var t ts=ts{"like"}
	type_ident_sub(t)
	
	var it interface{}=&t
	type_ident_sub(it)
}
func type_ident_sub(t interface{}){
	fmt.Println("enter type_ident_sub ",t)
	if str,ok:=t.(int);ok{
		fmt.Println("type is int ",str)
	}else if str,ok:=t.(string);ok {
		fmt.Println("typs is string ",str)
	}else if str,ok:=t.([]int);ok {
		fmt.Println("typs is []int ",str)
	}else if str,ok:=t.([]float32);ok {
		fmt.Println("typs is float32 ",str)
	}else if str,ok:=t.(ts);ok {
		fmt.Println("typs is struct ts ",str)
	}else if str,ok:=t.(func());ok {
		fmt.Println("typs is func() ",str)
	}else if str,ok:=t.(interface{});ok {
		fmt.Println("typs is interface{} ",str)
	}else{
		fmt.Println("-----other type-----")
	}
	fmt.Println("end of type_ident_sub ",t)
	fmt.Println()
	
}

func test1(){
	fmt.Println("enter func test1")
}

type ts struct{
	name string
}
type ti interface{
	testfunc(i int)
}
func (t ts)testfunc(i int){
	fmt.Println("testfunc")
}